Add an opaque, bounded application payload that firmware can exchange
between the split central and peripheral alongside the normal split
traffic, without ever taking priority over key events.
* `split_app` module: `SplitAppData` (a small, `MaxSize`, postcard
length-prefixed payload) plus four statics — `SPLIT_APP_TX`
(central -> peripheral), `SPLIT_APP_PERIPH_TX` (peripheral ->
central), the symmetric `SPLIT_APP_RX` inbox, and the `SPLIT_APP_LINK`
watch that reports split-link state to the application.
* Producers use `try_send` only (bounded, drop-on-full) so the split
read/write loops never block or get starved by application traffic;
key events are always polled first.
* The split driver and peripheral drain the application queues as the
lowest-priority arm of their outgoing selects and forward received
`SplitMessage::Application` payloads into the inbox.
* `SPLIT_APP_LINK` is state-based (a `Watch`), so a late-subscribing
application still observes the current link state; the `false -> true`
edge is a resync trigger. Link-down edges are emitted from a drop
guard so they survive async cancellation of the split session.
* On the peripheral the link is raised on the FIRST inbound message from
the central rather than on bare connection: over BLE, notifications to
a central that has not yet subscribed are silently dropped, so the
connection alone is not proof the application channel is usable.
Developed for a split keyboard port.
What
Why
RMK-based firmware sometimes needs to coordinate application-owned state across halves without adding hardware-specific meaning to the core split protocol. Per-key lighting is one consumer, but this API stays opaque and allocation-free.
Impact
Existing split behavior is unchanged unless the new queues are used. The implementation currently targets a single split peripheral and documents that limitation.
Checks